#ifndef COLAHEAPIMP_H
#define COLAHEAPIMP_H
#include "Hash.h"
#include "Cola.h"
#include "assert.h"
#include "Cadena.h"
#include "FuncionHash.h"
#include "FuncionIguales.h"
#include "iostream"
using namespace std;


template <class U>
class NodoHeap {
	public:
		U dato;
		int posicion;
		int prioridad;

		NodoHeap(const U &e, int pri) : dato(e),  prioridad(pri) , posicion(0){}
		NodoHeap(const NodoHeap<U> &n) : dato(n.dato), prioridad(n.prioridad), posicion(n.posicion)  {}

		NodoHeap<U> &operator=(const NodoHeap<U> &n) { dato = n.dato; prioridad = n.prioridad; posicion = n.posicion }

		virtual ~NodoHeap() {}
};

template <class T>
class ColaHeapImp : public Cola<T>{

public:
		// constructoras
		ColaHeapImp(int ,Puntero<FuncionHash<T>>,Puntero<FuncionIguales<T>> fi);
		virtual ~ColaHeapImp();
		virtual Puntero<Iterador<T>> ObtenerIterador() const ;
		//pre: Exista la cola
		bool encolarConPrioridad(T,int);
		//pos: devuelve true si en caso de cola acotada esta no estaba llena

		//pre: exista cola, un puntero a un elemento T
		bool desencolar(T&);
		//pos: devuelve true si se pudo conseguir el elemento, false en otro caso, apuntando la referencia a NULL, borra ese elemento.

		
		//pre: exista cola, un puntero a un elemento T
		bool proximo(T&);
		//pos: devuelve true si se pudo conseguir el elemento, false en otro caso, apuntando la referencia a NULL.

		//pre: Exista la cola
		void vaciar();
		//pos: vacia la cola
		
		//predicados

		//pre: Exista la cola
		bool esVacia();
		//pos:devuelve true si la cola esta vacia

		//pre: Exista la cola
		bool esLlena();
		//pos: en caso de una cola acotada devuelve true si esta esta llena
		void eliminar(T&);
	
		//Metodos auxiliares incluir comentarios

		void setPrioridadBase(int);

		int getPrioridadBase();

		
		int cambiarPuntajeRecurso(int ,int );
		//Le paso la posicion en la que esta el recurso y el puntaje nuevo este le cambia al recurso el puntaje y llama al reorganizar
		
		int reorganizar(int posicion);
		//Le paso la posicion y hace un filtrado descendente reordenando el heap
		
		void mostrarCola();
		//Muestra los elementos del heap
		T& devolverDato(T t);
		int largo();
		ColaHeapImp<T> &operator=(const ColaHeapImp<T> &);
		T& DevolverMaximo();
		bool EstaDefinido(T);


private:
	int maximo;
	NodoHeap<T> **heap;
	int tope;
	int deltaPrioridad;
	Puntero<Hash<T,int>> hash;
};
#include "ColaHeapImp.cpp"
#endif


